package com.ruoyi.common.utils;

import io.minio.MinioClient;
import io.minio.errors.MinioException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.utils.uuid.IdUtils;

import java.io.InputStream;
import java.util.List;

/**
 * MinIO工具类
 * 
 * @author ruoyi
 */
@Component
public class MinioUtils
{
    private static final Logger log = LoggerFactory.getLogger(MinioUtils.class);

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName:test}")
    private String bucketName;

    @Value("${minio.endpoint:http://59.110.39.34:9000}")
    private String endpoint;

    /**
     * 检查存储桶是否存在
     */
    public boolean bucketExists(String bucketName)
    {
        try
        {
            return minioClient.bucketExists(bucketName);
        }
        catch (Exception e)
        {
            log.error("检查存储桶是否存在失败", e);
            return false;
        }
    }

    /**
     * 创建存储桶
     */
    public boolean createBucket(String bucketName)
    {
        try
        {
            if (!bucketExists(bucketName))
            {
                minioClient.makeBucket(bucketName);
                log.info("创建存储桶成功: {}", bucketName);
            }
            return true;
        }
        catch (Exception e)
        {
            log.error("创建存储桶失败", e);
            return false;
        }
    }

    /**
     * 上传文件
     */
    public String uploadFile(MultipartFile file, String folder) throws Exception
    {
        // 检查并创建存储桶
        if (!bucketExists(bucketName))
        {
            createBucket(bucketName);
        }

        // 生成文件名
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = IdUtils.fastSimpleUUID() + extension;
        
        // 如果有文件夹，添加到路径中
        String objectName = StringUtils.isNotEmpty(folder) ? folder + "/" + fileName : fileName;

        try (InputStream inputStream = file.getInputStream())
        {
            // MinIO 6.0.13版本的API调用方式
            minioClient.putObject(bucketName, objectName, inputStream, file.getSize(), file.getContentType());
            
            // 返回文件访问URL
            return endpoint + "/" + bucketName + "/" + objectName;
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            throw new Exception("上传文件失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件
     */
    public boolean deleteFile(String objectName)
    {
        try
        {
            minioClient.removeObject(bucketName, objectName);
            return true;
        }
        catch (Exception e)
        {
            log.error("删除文件失败", e);
            return false;
        }
    }

    /**
     * 批量删除文件
     */
    public boolean deleteFiles(List<String> objectNames)
    {
        try
        {
            for (String objectName : objectNames)
            {
                minioClient.removeObject(bucketName, objectName);
            }
            return true;
        }
        catch (Exception e)
        {
            log.error("批量删除文件失败", e);
            return false;
        }
    }

    /**
     * 获取文件预签名URL（用于临时访问）
     */
    public String getPresignedUrl(String objectName, int expiry)
    {
        try
        {
            return minioClient.presignedGetObject(bucketName, objectName, expiry);
        }
        catch (Exception e)
        {
            log.error("获取预签名URL失败", e);
            return null;
        }
    }

    /**
     * 从URL中提取对象名称
     */
    public String extractObjectNameFromUrl(String url)
    {
        if (StringUtils.isEmpty(url) || !url.contains(bucketName))
        {
            return null;
        }
        
        int index = url.indexOf(bucketName + "/");
        if (index != -1)
        {
            return url.substring(index + bucketName.length() + 1);
        }
        return null;
    }
}